package ad_exercise_3.model;

import java.util.Random;

/**
 * Represents a card in the game UNO. Every card has a type, colour and value.
 * 
 * @author Pieter Koopman (number?)
 * @author Karen Berntsen (s0815799)
 * @author Erik Stens (s0615374)
 */
public class Card {
	private static final Random	random	= new Random();
	
	/**
	 * The type of card
	 */
	public enum CardType {
		NORMAL, TAKE_2, INVERT_DIRECTION, SKIP_TURN, CHOICE, CHOICE_TAKE_4;
		
		@Override
		public String toString() {
			switch (this) {
				case NORMAL:
					return "normal";
				case TAKE_2:
					return "take2";
				case INVERT_DIRECTION:
					return "invertDirection";
				case SKIP_TURN:
					return "skipTurn";
				case CHOICE:
					return "choice";
				case CHOICE_TAKE_4:
					return "choiceTake4";
				default:
					return "Unknown colour!";
			}
		}
	};
	
	/**
	 * The colour of the card
	 */
	public enum CardColour {
		YELLOW, GREEN, RED, BLUE, UNKNOWN;
		
		@Override
		public String toString() {
			switch (this) {
				case YELLOW:
					return "yellow";
				case GREEN:
					return "green";
				case BLUE:
					return "blue";
				case RED:
					return "red";
				case UNKNOWN:
				default:
					return "Unknown colour!";
			}
		}
	};
	
	/**
	 * A card is represented by it's type, colour and value
	 */
	private CardType	cardType;
	private CardColour	cardColour;
	private int			value;
	
	public Card(CardColour cardColour, CardType cardType, int value) {
		// TODO checks inbouwen
		
		this.cardColour = cardColour;
		this.cardType = cardType;
		this.value = value;
	}
	
	public Card(CardColour cardColour, int value) {
		this(cardColour, CardType.NORMAL, value);
	}
	
	public Card(CardColour cardColour, CardType cardType) {
		this(cardColour, cardType, -1);
	}
	
	public Card(CardType cardType) {
		this(CardColour.UNKNOWN, cardType, -1);
	}
	
	public CardColour getCardColour() {
		return cardColour;
	}
	
	public void setCardColour(CardColour cardColour) {
		if (cardType == CardType.CHOICE || cardType == CardType.CHOICE_TAKE_4) {
			this.cardColour = cardColour;
		}
	}
	
	public CardType getCardType() {
		return cardType;
	}
	
	public int getValue() {
		return value;
	}
	
	/**
	 * Checks whether this card fits on 'card'
	 * 
	 * @param card
	 *            the card on which this card has to fit
	 * @return if the card fits
	 */
	public boolean cardFits(Card card) {
		if (cardColour == card.cardColour) {
			return true;
		}
		
		if (cardType == card.cardType) {
			if (cardType != CardType.NORMAL) {
				return true;
			} else {
				return value == card.value;
			}
		}
		
		if (cardType == CardType.CHOICE || cardType == CardType.CHOICE_TAKE_4) {
			return true;
		}
		
		return false;
	}
	
	@Override
	public String toString() {
		StringBuilder result = new StringBuilder();
		
		if (cardColour != CardColour.UNKNOWN) {
			result.append(cardColour.toString() + " ");
		}
		
		if (cardType != CardType.NORMAL) {
			result.append(cardType.toString());
		} else {
			result.append(value);
		}
		
		return result.toString();
	}
	
	public static CardColour getRandomCardColour() {
		int colourIndex = random.nextInt(4);
		return CardColour.values()[colourIndex];
	}
}
